import { i18n } from "@/locale";
import { currentRoute, LOGIN_PATH, removeQueryString } from "@/router";
import { useAuthStore } from "@/store/modules/auth";
import { getStorage } from ".";
// import MD5 from "crypto-js/md5";

// 接口签名
// const API_SAFE = true;
// const API_KEY = "8oJliIOB2gKLFHec0jmM7Z5S9Y4UdQnP";
// const API_KEY = "";
// 启用 refreshToken
const ENABLED_REFRESH_TOKEN = false;
// 请求头
const HeaderEnum = {
  ACCESS_TOKEN: "Authorization",
  REFRESH_TOKEN: "Pass",
  I18N: "Language",
  SIGN: "Sign",
  EN: "en-US",
};
// code值
const CodeEnum = {
  SUCCESS: 200,
  ACCESS_TOKEN_INVALID: 4003,
  REFRESH_TOKEN_INVALID: 4004,
};
// H5开发环境做跨域处理
let baseURL = import.meta.env.VITE_APP_BASE_URL;
// // #ifdef H5
// if (import.meta.env.DEV) {
//   baseURL = import.meta.env.VITE_APP_PROXY_PREFIX;
// }
// // #endif
// 请求重试队列，每一项将是一个待执行的函数形式
let requests = [];
// 是否正在刷新token的标记
let isRefreshing = false;

// 创建请求函数
const request = (config) => {
  return new Promise((resolve, reject) => {
    // 处理请求前的配置
    const requestConfig = handleRequestConfig(config);

    // 发起请求
    uni.request({
      ...requestConfig,
      success: (response) => {
        handleResponse(response, config).then(resolve).catch(reject);
      },
      fail: (error) => {
        handleError(error, config);
        reject(error);
      },
      complete: () => {
        // 隐藏加载提示
        if (config.custom?.loading) {
          uni.hideLoading();
        }
      },
    });
  });
};

// 处理请求配置
function handleRequestConfig(config) {
  // 处理加载提示
  if (config.custom?.loading) {
    uni.showLoading({
      title: config.custom.loadingText || "正在加载",
      mask: config.custom.loadingMask ?? true,
    });
  }

  // 构建请求头
  const header = {
    "Content-Type": "application/json",
    ...config.headers,
  };
  const authStore = useAuthStore();
  console.log(authStore);
  // 添加认证令牌
  const token = getStorage("accessToken");
  if (token) {
    header[HeaderEnum.ACCESS_TOKEN] = token;
  }

  // 添加国际化头部
  header[HeaderEnum.I18N] = i18n.global.locale.value || HeaderEnum.EN;

  // 构建最终配置
  return {
    url: `${baseURL}${config.url}`,
    data: config.data,
    method: config.method?.toUpperCase() || "GET",
    header: header,
    timeout: config.timeout || 60000,
  };
}

// 处理响应
async function handleResponse(response, config) {
  const { statusCode, data } = response;

  // 处理HTTP状态码
  if (statusCode !== 200) {
    const errMsg =
      {
        404: "您所请求的资源无法找到",
        500: "服务器内部错误，无法完成请求",
      }[statusCode] || "异常错误";

    uni.showToast({
      title: errMsg,
      icon: "none",
    });

    throw new Error(errMsg);
  }

  // 处理业务状态码
  const { code, msg } = data;

  if (code === 200) {
    return data;
  }

  if (code === 401) {
    const authStore = useAuthStore();

    if (!ENABLED_REFRESH_TOKEN || !authStore.refreshToken) {
      authStore.signOut();
      redirectToLoginPage();
      throw new Error(msg || "access token invalid");
    }

    // 处理token刷新
    return handleTokenRefresh(config, authStore);
  }

  if (code === CodeEnum.REFRESH_TOKEN_INVALID) {
    throw new Error(msg || "异常错误");
  }

  uni.showToast({
    title: msg || "系统出错",
    icon: "none",
  });

  throw new Error(msg || "异常错误");
}

// 处理错误
function handleError(error, config) {
  uni.showToast({
    title: "网络请求失败",
    icon: "none",
  });
}

// 处理令牌刷新
function handleTokenRefresh(config, authStore) {
  return new Promise((resolve) => {
    // 将当前请求加入队列
    requests.push(() => {
      resolve(request(config));
    });

    if (!isRefreshing) {
      isRefreshing = true;

      // 发起刷新token的请求
      authStore
        .refresh({
          [HeaderEnum.REFRESH_TOKEN]: authStore.refreshToken,
        })
        .then(() => {
          // 刷新token成功后，重新发起队列中的请求
          requests.forEach((cb) => cb());
        })
        .catch(() => {
          // 刷新token失败，登出并跳转到登录页
          authStore.signOut();
          redirectToLoginPage();
        })
        .finally(() => {
          // 重置队列和刷新状态
          requests = [];
          isRefreshing = false;
        });
    }
  });
}

// 重定向到登录页面
function redirectToLoginPage() {
  const path = currentRoute();
  if (removeQueryString(path) !== LOGIN_PATH) {
    uni.redirectTo({
      url: `${LOGIN_PATH}?redirect=${encodeURIComponent(path)}`,
    });
  }
}

// 添加请求方法简写
["get", "post", "put", "delete"].forEach((method) => {
  request[method] = (url, data, config = {}) => {
    return request({
      url,
      data,
      method,
      ...config,
    });
  };
});

export default request;
